import JSZip from 'jszip';
import store from '../store';
import axios from 'axios';
import { standardFormatNoHour } from '@/filters/date';

/**
 * @returns {String} 当前浏览器名称
 */
export const getExplorer = () => {
  const ua = window.navigator.userAgent;
  const isExplorer = (exp) => {
    return ua.indexOf(exp) > -1;
  };
  if (isExplorer('DingTalk')) return 'DingTalk'; else if (isExplorer('Feishu')) return 'Feishu'; else if (isExplorer('MSIE')) return 'IE'; else if (isExplorer('Firefox')) return 'Firefox'; else if (isExplorer('Chrome')) return 'Chrome'; else if (isExplorer('Opera')) return 'Opera'; else if (isExplorer('Safari')) return 'Safari';
};
export const isIphoneOrAndroid = () => {
  const ua = navigator.userAgent;
  const ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
  const isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
  const isAndroid = ua.match(/(Android)\s+([\d.]+)/);
  const isMobile = isIphone || isAndroid;
  return isMobile;
};
export const isIphone = () => {
  const ua = navigator.userAgent;
  const ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
  const isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
  return !!isIphone;
};
export const isMobile = () => {
  return /(iphone|ipad|ipod|itouch|ios|android|windows phone)/i.test(navigator.userAgent.toLowerCase());
};

export const isIpad = () => {
  const ua = navigator.userAgent;
  return ua.match(/(iPad).*OS\s([\d_]+)/) || /(ipad|ipod)/i.test(ua.toLowerCase());
};
/**
 * @returns {String} 当前IE浏览器版本号
 */
export const getIEVersion = () => {
  var userAgent = navigator.userAgent; // 取得浏览器的userAgent字符串
  var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1; // 判断是否IE<11浏览器
  var isEdge = userAgent.indexOf('Edge') > -1 && !isIE; // 判断是否IE的Edge浏览器
  var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;
  if (isIE) {
    // var reIE = new RegExp('MSIE (\\d+\\.\\d+);');
    // reIE.test(userAgent);
    var fIEVersion = parseFloat(RegExp['$1']);
    if (fIEVersion === 7) {
      return 7;
    } else if (fIEVersion === 8) {
      return 8;
    } else if (fIEVersion === 9) {
      return 9;
    } else if (fIEVersion === 10) {
      return 10;
    } else {
      return 6;// IE版本<=7
    }
  } else if (isEdge) {
    return 'edge';// edge
  } else if (isIE11) {
    return 11; // IE11
  } else {
    return -1;// 不是ie浏览器
  }
};

// 判断是否是数字
export const isNumber = (val) => {
  var regPos = /^\d+(\.\d+)?$/; // 非负浮点数
  var regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; // 负浮点数
  if (regPos.test(val) || regNeg.test(val)) {
    return true;
  } else {
    return false;
  }
};

// 判断是否是移动端
/* eslint-disable eqeqeq */
export const browserRedirect = () => {
  const sUserAgent = navigator.userAgent.toLowerCase();
  const bIsIpad = sUserAgent.match(/ipad/i) == 'ipad';
  const bIsIphoneOs = sUserAgent.match(/iphone os/i) == 'iphone os';
  const bIsMidp = sUserAgent.match(/midp/i) == 'midp';
  const bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == 'rv:1.2.3.4';
  const bIsUc = sUserAgent.match(/ucweb/i) == 'ucweb';
  const bIsAndroid = sUserAgent.match(/android/i) == 'android';
  const bIsCE = sUserAgent.match(/windows ce/i) == 'windows ce';
  const bIsWM = sUserAgent.match(/windows mobile/i) == 'windows mobile';
  return (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM);
};

export const ipad = () => {
  const ua = navigator.userAgent;
  const isSafari = ua.indexOf('Safari') != -1 && ua.indexOf('Version') != -1;
  const isIphone = ua.indexOf('iPhone') != -1 && ua.indexOf('Version') != -1;
  return (isSafari && !isIphone && 'ontouchend' in document);
};

// 防抖
export const debounce = (func, wait, immediate) => {
  let timeout, args, context, timestamp, result;
  const later = function() {
    const last = new Date() - timestamp;
    if (last < wait && last >= 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      if (!immediate) {
        // 执行 func 函数
        result = func.apply(context, args);
        if (!timeout) {
          context = args = null;
        }
      }
    }
  };
  // 闭包返回的函数，是可以传入参数的
  return function() {
    context = this;
    args = arguments;

    // 每次触发函数，更新时间戳
    timestamp = new Date();

    // 立即触发需要满足两个条件
    const callNow = immediate && !timeout;

    // 设置 wait seconds 后触发 later 方法
    if (!timeout) {
      timeout = setTimeout(later, wait);
    }

    if (callNow) {
      result = func.apply(context, args);
      // 解除引用
      context = args = null;
    }
    return result;
  };
};

/**
 * elementUI 的el-cascader组件有一个bug，v-model 传入的数据必须与options的顺序一致，否则删除时会对应不上
 * 所以这个方法作用是，让 value 数据按照 list 进行排序
 * @param {Array} value 填充的数据
 * @param {Array} list 列表的数据
 */
export function cascaderSoft(value, list) {
  if (!value || !list) return [];
  const idList = [];
  const getId = (item, ans) => {
    if (item.id) {
      ans.push(item.id);
    }
    if (item.children && item.children.length) {
      for (let i = 0; i < item.children.length; i++) {
        getId(item.children[i], ans);
      }
    }
  };
  for (let i = 0; i < list.length; i++) {
    getId(list[i], idList);
  }
  value.sort((a, b) => {
    const preIndex = idList.indexOf(a);
    const curIndex = idList.indexOf(b);
    return preIndex - curIndex;
  });
}

export function setChildren(item) { // 获取运营模式
  if (!item.children || item.children.length === 0) {
    item.children = null;
    return;
  }
  item.children.forEach(i => {
    setChildren(i);
  });
}

export function isJSON(str) { // 判断字符串是否为json
  if (typeof str == 'string') {
    try {
      const obj = JSON.parse(str);
      if (typeof obj == 'object' && obj) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      return false;
    }
  }
}

/**
 * 16进制颜色转 rgba色
 * @param hexColor
 * @param alphaMaxVal 一般这里就是1或者255 默认以1为基准 如果最大值是255 就写255
 * @returns {*[]}
 */
export function hexColorToRgba(hexColor, alphaMaxVal = 1) {
  hexColor = hexColor.replace('#', '');
  // 用于分割16进制色彩通道
  const reg = new RegExp('\\w{1,2}', 'g');
  // 分割颜色通道
  let rgbaArray255 = hexColor.match(reg);
  rgbaArray255 = rgbaArray255.map((channel, index) => {
    // 计算每个通道的10进制值
    const colorVal = parseInt(channel, 16);
    if (index === 3) {
      // 这是alpha通道
      return Math.round(colorVal / (255 / alphaMaxVal) * 100) / 100;
    }
    return colorVal;
  });
  return rgbaArray255;
}

/**
 * rgba色改透明度
 */
export function changeColorAlphaVal(color, alpha = 1) {
  if (!color || !color.startsWith('rgba')) return color;
  if (typeof alpha !== 'number' || Number(alpha) > 1) {
    alpha = 1;
  }
  const values = color
    .replace(/rgba?\(/, '')
    .replace(/\)/, '')
    .replace(/[\s+]/g, '')
    .split(',');
  if (values.length < 3) return color;
  values[3] = (values[3] || 1) * alpha;
  return `rgba(${values.join()})`;
}
// 判断两个对象是否相等
export function isObjEqual(a, b) {
  const classNameA = toString.call(a);
  const classNameB = toString.call(b);
  // 如果数据类型不相等，则返回false
  if (classNameA !== classNameB) {
    return false;
  } else {
    // 如果数据类型相等，再根据不同数据类型分别判断
    if (classNameA === '[object Object]') {
      for (const key in a) {
        if (!isObjEqual(a[key], b[key])) return false;
      }
      for (const key in b) {
        if (!isObjEqual(a[key], b[key])) return false;
      }
      return true;
    } else if (classNameA === '[object Array]') {
      if (a.length !== b.length) {
        return false;
      } else {
        for (let i = 0, len = a.length; i < len; i++) {
          if (!isObjEqual(a[i], b[i])) return false;
        }
        return true;
      }
    } else if (classNameA === '[object Function]') {
      return a.toString() === b.toString();
    } else {
      return Object.is(a, b);
    }
  }
}
export function isArrEqual(array1, array2) {
  return array1.length == array2.length && array1.every(function(v, i) { return v === array2[i]; });
}
// 判断某个数组中是否包含另一个数组
export function isContained(a, b) {
  if (!(a instanceof Array) || !(b instanceof Array)) return false;
  if (a.length < b.length) return false;
  var aStr = a.toString();
  for (var i = 0, len = b.length; i < len; i++) {
    if (aStr.indexOf(b[i]) == -1) return false;
  }
  return true;
}
export function _debounce(fn, delay = 300) {
  var timer = null;
  return function() {
    var _this = this;
    var args = arguments;
    if (timer) clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(_this, args);
    }, delay);
  };
}

/**
 * 动态设置viewport
 * @param {*} initialScale 初始缩放
 * @param {*} maximumScale 最大缩放
 * @param {*} minimumScale 最小缩放
 */
export function setMetaViewport(initialScale = '0.5', maximumScale = '3.0', minimumScale = '0.1') {
  const viewport = document.querySelector('meta[name="viewport"]');
  viewport.setAttribute('content', `width=device-width, initial-scale=${initialScale}, maximum-scale=${maximumScale}, minimum-scale=${minimumScale}, user-scalable=yes`);
}

/**
 * PC <==> 移动 切换
 * @param {*} routerName 路由名称
 * @param {*} autoSwitch 是否路由跳转自动切换
 */
export function switchMobile(routerName, autoSwitch = false) {
  const isMobileApp = isMobile();
  const showMobilePage = store.state.app.showMobilePage;
  const mobilePage = store.state.app.mobilePage;
  // 手动切换时：如果之前的模式为 PC 端（即：showMobilePage为false）那么可以切换到移动端
  // 路由跳转自动切换时：只验证当前设备和mobilePage
  if (isMobileApp && (autoSwitch || !showMobilePage) && mobilePage.includes(routerName)) {
    // 移动端适配页面
    setMetaViewport('1.0', '1.0', '1.0');
    store.dispatch('ToggleShowType', true);
  } else {
    // PC端适配页面
    setMetaViewport();
    store.dispatch('ToggleShowType', false);
  }
}

export function generateUUID() {
  let d = new Date().getTime();
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    const r = (d + Math.random() * 16) % 16 | 0;
    d = Math.floor(d / 16);
    return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
  });
}

// 生成一个小于Int类型最大值的数
export function createIntTypeNumber() {
  const str = generateUUID().replace(/-/g, '');
  const sliceStart = Math.floor(Math.random() * (str.length - 7));
  return _.parseInt(str.slice(sliceStart, sliceStart + 7), 16);
}

export const commonOptions = [
  { value: 0, label: '草稿中' },
  { value: 1, label: '审批中' },
  { value: 2, label: '未过审' },
  { value: 3, label: '已作废' },
  { value: 4, label: '已完成' },
  { value: 5, label: '待提交' }
];

export function arrRepeat(data) {
  const hash = {};
  const data2 = data.reduce((preVal, curVal) => {
    if (!hash[curVal.id]) {
      hash[curVal.id] = true;
      preVal.push(curVal);
    }
    return preVal;
  }, []);
  return data2;
}

export function formatName(data, key = 'name') {
  if (!data || !data.length || data.length === 0) {
    return '--';
  }
  return data.map(item => {
    return item[key];
  }).join();
}

// 判断参数是否为空
export function isEmpty(value) {
  if (value === null || value === undefined) {
    return true;
  }
  if (typeof value === 'string' && value.trim() === '') {
    return true;
  }
  if (Array.isArray(value) && value.length === 0) {
    return true;
  }
  if (typeof value === 'object' && Object.keys(value).length === 0) {
    return true;
  }
  return false;
}

/**
 * 打包下载
 * @param {*} list {url: string}[]
 */
export async function downloadWithZip(list, zipName) {
  const zip = new JSZip();
  const downloadList = [];
  list.forEach((i) => {
    downloadList.push(getImgBlob(i.url));
  });
  try {
    const res = await window.Promise.allSettled(downloadList);
    res.forEach((i, index) => {
      if (i.status === 'fulfilled') {
        zip.file(list[index].name || `image${index}.png`, i.value);
      }
    });
    const time = standardFormatNoHour((new Date().getTime() / 1000), 'YYYYMMDD');
    zip.generateAsync({ type: 'blob' }).then((content) => {
      const url = window.URL.createObjectURL(content);
      const name = `${zipName || ''}${time}`;
      downloadFile(url, name);
    });
  } catch (error) {
    return window.Promise.reject(error);
  }
}

async function getImgBlob(url, fileName) {
  try {
    const { data } = await axios({
      method: 'get',
      url,
      responseType: 'blob'
    });
    return data;
  } catch (error) {
    return '';
  }
}
function downloadFile(url, name) {
  const a = document.createElement('a');

  a.href = url;
  a.download = name;
  a.click();
}
